home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Commodore Free 11
/
Commodore_Free_Issue_11_2007_Commodore_Computer_Club.d64
/
t.hexfiles 6
< prev
next >
Wrap
File List
|
2023-02-26
|
8KB
|
270 lines
u Hexfiles part 6
By Jason Kelk
http://www.oldschoolgaming.com/
Hello children, today we're going to be
looing at raster interrupts & later on
we're going to be making one of our
own. You'll need the inside of a toilet
roll, some sticky backed plastic & 2
washing up liquid bottles remember to
use plasticine behind card when you
want to make a hole with your scissors
& you may want the help of a
responsible adult when cutting things.
Or at least an irresponsible adult,
since they're more fun. Before I start
a word of warning; the first piece of
example code in this article uses
stroboscopic effects & some viewers may
find these effects at the least
uncomfortable to watch.
If you have a history of epilepsy or an
adversion to strobe effects, don't
execute the first piece of code, just
read the documentation & dissection.
This only applies to the file called
rasterD1.asm & the later files can be
executed with no difficulty. Last
issue I left you all messing around
with the sine curves on that little
demo we did, didn't I? So, did you
enjoy yourselves? Good! Okay, now up
until now our code has been using
what's called "runtime", & in theory
anything can be written that way. But
the C64 can also do something called
an interrupt which, as the name
suggests, involves interrupting the
runtime code & popping off to do some-
thing else. Normally the C64 interrupt
is set to a part of the Kernel ROM (the
set of housekeeping code that C=
supplied with the machine) & it takes
care of reading the keyboard & a few
other little tasks. Since we believe in
leading by example I won't just go off
& teach you about all the different
kinds of interrupt, for now the only
one you need is the raster interrupt.
If you remember our demo, it waited for
a raster line using $D012 & then did
something, but using a raster interrupt
we can do something else on the runtime
& whenever that raster position comes
around, the machine interrupts what the
runtime code is doing & performs a few
other tasks. Okay, so we need some code
to look at to get this concept across,
Load Turbo Assembler (it's on this
issue's cover disk) & the source file
rasterD1.asm As usual I'll do a break-
down of what you've just loaded in a
second, but for now assemble & run it
with SYS2304. The code appears to have
run but but the cursor has come back up
again & the border is flashing very
rapidly, right? That's what we mean by
interrupt, the C64 is stopping the run-
time code (where BASIC & our previous
pieces of code work from) once a frame
& is doing a little INC $D020 to flash
the border colour. And we can do any-
thing from interrupt, play music, move
sprites, scroll the screen & with more
than one split, change what the VIC
chip is doing at various points down
the screen. Okay, so lets take a look
at our code:
split = $00
* = $0900 sei First off, we set up
split as a label, giving it an actual
value of $00. If we change that value
we can alter
where the raster actually takes place
on the screen, from line $00 (as here)
to line $FF. And, as before, we set
our code start with the *, this time
to $0900 (2304). That's followed by a
quick SEI to turn off the interrupts,
so that nothing goes amiss while we
change things.
lda #<int
sta $0314
lda #>int
sta $0315
$0314 and $0315 are where the C64
looks to find the address it should
call for the interrupt, normally it's
set to $EA31 (the housekeeping routines
we mentioned earlier) but we want it
pointing to our code called int, which
will later call $EA31 itself. The LDA
#< and LDA #> will get the memory
location of int for us, saving us from
working it out; in this case, $0314
contains $27 & $0315 gets $40, since
INT gets put at $4027 by the assembler.
This reverse the numbers system is
called lowbyte/highbyte format (since
the lowbyte, the $27 here, goes first &
the highbyte goes second) & from here
onwards, reference to the lowbyte will
mean the last two digits of a hex
number & highbyte will mean the first
two.
lda #$7f
sta $dc0d
sta $dd0d
Despite the interrupts being "halted"
by the SEI command earlier, the
interrupt flags themselves can still
be set; writing $7F over $DC0D &
clearing the top bit prevents a rogue
IRQ interrupt occurring whilst doing
the same to $DD0D prevents rogue NMI
interrups. The latter are less common
but more likely the longer the program
spends in "SEI mode" so this is a nice
little precaution to prevent some hard
to track erratic crashes that may occur
as your code becomes more complex.
lda #split
sta $d012
lda #$1b
sta $d011
Now we set the position of the split
we want by writing it to $D012, the
raster register. In this case it's
defined by the label split, as we've
previously mentioned, so it will be
positioned on rasterline $00 which is
at the top of the screen. The reason
we set $D011 is to clear the Most
Significant Bit (or MSB) of the raster,
since there are over 256 raster lines
on the screen (on PAL machines, as used
in the U.K. & Europe) a single $00 to
$FF range is too small so one of the
bits of $D011 is used as a ninth bit to
give a total range of $000 to $1ff.
lda #$01
sta $d019
sta $d01a
$D019 is an indicator, the first bit
tells us when an interrupt has
happened, so we're just priming it here
ready for the main routine & then
writing to $D01A in order to tell the
C64 that we want a raster interrupt,
not any of the other kinds it has
available.
cli rts
Ah, now CLI is a new command. It's
pretty much the reverse of SEI, it
turns all the interrupts back on &
therefore enables our new interrupt.
Then it's an RTS to take us back to
BASIC, at least for the runtime code, &
that's the interrupt setup out of the
way! Now it's time to get onto what
happens during the interrupt itself.
int lda $d019
and #$01
sta $d019
int is the routine we pointed $0314 &
$0315 to earlier, so it's now where the
C64 looks when a raster interrupt is
called. At this point, we want to check
$D019 to see if the first bit is 0 or 1
(in other words, if the Most Signifi-
cant Bit of the raster is set, since
$D012 can be $00 twice during the
screen & we want the one where the MSB
isn't set) and..
bne dosplit
jmp $ea81
..if it's the former we can go on to
our raster split, the routine dosplit
(or "do split"). Otherwise we call
$EA81, which is another of the little
housekeeping routines from the C64 ROM
that does most of what our house-
keeping friend $EA31 does but without
the keyboard reading. After all, we
don't want the keyboard read more than
once every 50th of a second, it causes
all sorts of problems!
dosplit
lda #split
sta $d012
Since the value we put into $D012 gets
cleaned out when the interrupt is
triggered and a split happens, we have
to put it back in again for the next
frame.
inc $d020
Then we increment the border colour,
just to make what's happening a little
more noticable (otherwise it would look
exactly the same as a normal system
interrupt).
jmp $ea31 And to round things off we
call $EA31 which, as I've already
mentioned, is where the C64 normally
goes on it's own interrupts (the values
in $0314 and $0315 are $31 & $EA
respectively) so that the housekeeping
happens.
Well, that's pretty much your lot
again, but just for something to play
with until I get back next issue, load
rasterD2.asm, then assemble the code &
run it. Most of the code & data is from
the original demo which we've covered
quite extensively before now but a few
slight changes have been made. The most
major are that it now runs using a
raster interrupt and the settings for
$D018 & the addition of a custom
character set but I'll explain the
latter in more detail next time. Once
again, if you have any queries,
comments or suggestions contact me &
we'll do lunch. The source code for the
routines above can be downloaded here
for easier reference
http://www.oldschoolgaming.com/
files/c64/hexDfiles/pa rtD6Dfiles.zip
Copyright Oldschool gaming Reprinted
with permission of Jason Kelk